/*
 * 版权所有 (c) 华为技术有限公司 2022-2022
 */
package com.huawei.cameratest.util;

import android.util.Log;
import android.util.Range;
import android.util.Size;
import com.huawei.cameratest.data.StreamConfig;

import java.io.FileNotFoundException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class MultiStreamTagUtil {
    private static final String TAG = "MultiStreamTagUtil";

    // [StreamCount, StreamId1, MODE1, StreamId2, MODE2…]
    public static int[] constructIntTags(List<StreamConfig> streamConfigs, String method) {
        int streamCount = 0;
        if (streamConfigs.size() < 1) {
            return null;
        }
        List<Integer> values = new ArrayList<>();
        values.add(streamConfigs.size());
        Method streamConfigMethod;
        Object methodReturnValue;
        for (StreamConfig streamConfig : streamConfigs) {
            Class streamConfigClass = streamConfig.getClass();
            try {
                streamConfigMethod = streamConfigClass.getDeclaredMethod(method);
                methodReturnValue = streamConfigMethod.invoke(streamConfig);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            if (methodReturnValue != null) {
                streamCount++;
                values.add(streamConfig.getStreamId());
                values.add((int) methodReturnValue);
            }
        }
        int[] result = new int[values.size()];
        for (int i = 0; i < values.size(); i++) {
            result[i] = values.get(i);
        }
        result[0] = streamCount;
        Log.i(TAG, "constructIntTags " + method + ":" + toString(result));
        if (result.length < 2) {
            return null;
        } else {
            return result;
        }
    }

    public static Byte[] constructByteTags(List<StreamConfig> streamConfigs, String method) {
        Byte streamCount = 0;
        if (streamConfigs.size() < 1) {
            return null;
        }
        List<Byte> values = new ArrayList<>();
        values.add((byte) streamConfigs.size());
        Method streamConfigMethod;
        Object methodReturnValue;
        for (StreamConfig streamConfig : streamConfigs) {
            Class streamConfigClass = streamConfig.getClass();
            try {
                streamConfigMethod = streamConfigClass.getDeclaredMethod(method);
                methodReturnValue = streamConfigMethod.invoke(streamConfig);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
                return null;
            }
            if (methodReturnValue != null) {
                streamCount++;
                values.add(streamConfig.getStreamId().byteValue());
                values.add((byte) methodReturnValue);
            }
        }
        Byte[] result = new Byte[values.size()];
        for (int i = 0; i < values.size(); i++) {
            result[i] = values.get(i);
        }
        result[0] = streamCount;
        Log.i(TAG, "constructByteTags " + method + ":" + toString(result));
        if (result.length < 2) {
            return null;
        } else {
            return result;
        }
    }

    public static int[] constructResolutionTags(List<StreamConfig> streamConfigs) {
        int streamCount = 0;
        if (streamConfigs.size() < 1) {
            return null;
        }
        List<Integer> values = new ArrayList<>();
        values.add(streamConfigs.size());
        for (StreamConfig streamConfig : streamConfigs) {
            streamCount++;
            Size size = toSize(streamConfig.getResolution());
            values.add(streamConfig.getStreamId());
            values.add(size.getWidth());
            values.add(size.getHeight());
        }
        int[] result = new int[values.size()];
        for (int i = 0; i < values.size(); i++) {
            result[i] = values.get(i);
        }
        result[0] = streamCount;
        Log.i(TAG, "constructResolutionTags :" + toString(result));
        if (result.length < 2) {
            return null;
        } else {
            return result;
        }
    }

    public static int[] constructQPTags(List<StreamConfig> streamConfigs) {
        int streamCount = 0;
        if (streamConfigs.size() < 1) {
            return null;
        }
        List<Integer> values = new ArrayList<>();
        values.add(streamConfigs.size());
        for (StreamConfig streamConfig : streamConfigs) {
            Integer qpMin = streamConfig.getQpMin();
            Integer qpMax = streamConfig.getQpMax();
            if (qpMin == null || qpMax == null || qpMax < qpMin) {
                Log.i(TAG, "invalid QP value " + "streamId" + streamConfig.getStreamId() + "min " + qpMin + " max" +qpMax );
                continue;
            }
            streamCount++;
            values.add(streamConfig.getStreamId());
            values.add(qpMin);
            values.add(qpMax);
        }
        int[] result = new int[values.size()];
        for (int i = 0; i < values.size(); i++) {
            result[i] = values.get(i);
        }
        result[0] = streamCount;
        Log.i(TAG, "constructQPTags :" + toString(result));
        if (result.length < 2) {
            return null;
        } else {
            return result;
        }
    }

    // steamId 2代表预览
    public static Byte[] constructTargetTags(String action, int steamId) {
        Byte[] results = new Byte[3];
        results[0] = 0;
        results[1] = (byte) steamId;
        if ("add".equalsIgnoreCase(action)) {
            results[2] = 1;
        } else {
            results[2] = 0;
        }
        return results;
    }

    public static Size toSize(String string) {
        String[] strings = string.split("x");
        int weight = Integer.parseInt(strings[0].trim());
        int height = Integer.parseInt(strings[1].trim());
        Size size = new Size(weight, height);
        return size;
    }

    public static Range toRange(String string) {
        string = string.substring(1, string.length() - 1);
        String[] strings = string.split("\\,");
        Range range = new Range(Integer.parseInt(strings[0].trim()), Integer.parseInt(strings[1].trim()));
        return range;
    }

    public static String toString(int[] values) {
        String results = "";
        for (int value : values) {
            results = results + "," + value;
        }
        return results;
    }

    public static String toString(Byte[] values) {
        String results = "";
        for (int value : values) {
            results = results + "," + value;
        }
        return results;
    }
}